package com.rajesh.messageservice;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

import com.rajesh.messageservice.bean.UserInfo;
import com.rajesh.messageservice.crack.AppAttachAnnouncer;
import com.rajesh.messageservice.crack.ContactService;
import com.rajesh.messageservice.crack.DatabaseCracker;
import com.rajesh.messageservice.crack.HeadImgService;
import com.rajesh.messageservice.crack.MessageAnnouncer;
import com.rajesh.messageservice.crack.WeChatCracker;
import com.rajesh.messageservice.helper.GlobalConfig;
import com.rajesh.messageservice.helper.PollingUtils;
import com.rajesh.messageservice.helper.QueryStrings;

import net.sqlcipher.database.SQLiteDatabase;

import java.io.IOException;

public class MsgSvc extends Service {

    static final String TAG = "MsgSvc";
    private DatabaseObserver databaseObserver = null;
    private Announcer[] announcer = null;
    private DatabaseCracker databaseCracker = null;
    private TickReceiver tickReceiver = null;

    public static final String StartMessageService = "rajesh.action.START_MESSAGESERVICE";

    @Override
    public void onCreate() {
        super.onCreate();
        SQLiteDatabase.loadLibs(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try{
            this.registerTickReceiver();
            this.createDatabaseCracker();
            this.initAnnouncer();
            PollingUtils.startService(this, GlobalConfig.ContactSyncTickInterval, ContactService.class, ContactService.ACTION);
            PollingUtils.startService(this, GlobalConfig.ImageSyncTickInterval, HeadImgService.class, HeadImgService.ACTION);
            this.registerClient();
        }catch (Exception e){
            e.printStackTrace();
        }
        return super.onStartCommand(intent, START_FLAG_RETRY, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(tickReceiver);

        //send broadcast to protector
        Intent intent = new Intent();
        intent.setAction(StartMessageService);
        sendBroadcast(intent);

        super.onDestroy();
    }

    private void registerClient() throws IOException {
        Intent intent = new Intent(MsgBroadcastReceiver.ClientRegister);
        intent.putExtra("Uin", WeChatCracker.getUin());

        if(databaseCracker != null){
            UserInfo userInfo = databaseCracker.single(UserInfo.class, QueryStrings.QUERY_CURRENT_USER_INFO);
            intent.putExtra("UserName", userInfo.getUserName());
            intent.putExtra("NickName", userInfo.getNickName());
            sendBroadcast(intent);
        }
    }

    private void createDatabaseCracker(){
        if(databaseCracker == null){
            try{
                databaseCracker = DatabaseCracker.createInstance(this);
            }catch (Exception e){
                e.printStackTrace();
                Toast.makeText(MsgSvc.this, e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void initAnnouncer() throws IOException {
        if(announcer == null){
            announcer = new Announcer[]{
                    new MessageAnnouncer(MsgSvc.this, databaseCracker) ,
                    new AppAttachAnnouncer(MsgSvc.this, databaseCracker)
            };
            databaseObserver = new DatabaseObserver(WeChatCracker.getUserDataBasePath(true), WeChatCracker.computePragmaKey(this), announcer);
            databaseObserver.startWatching();
        }
    }

    private void registerTickReceiver(){
        tickReceiver = new TickReceiver(){
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                switch (action){
                    case Intent.ACTION_TIME_TICK:{
                        ProtectorService.startActionCheckProtectorRunning(context);
                        break;
                    }
                    default:{
                        break;
                    }
                }
            }
        };

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_TIME_TICK);
        registerReceiver(tickReceiver, intentFilter);
    }
}
